//! 数据网关数据源插件
//! 
//! 提供各种数据源的连接和查询功能

pub mod memory;
pub mod file_system;
pub mod http_api;
pub mod postgresql;
pub mod redis;
pub mod mysql;
pub mod sqlite;
pub mod mongodb;
pub mod s3;
pub mod elasticsearch;

pub use memory::MemoryDataSource;
pub use file_system::FileSystemDataSource;
pub use http_api::HttpApiDataSource;
pub use postgresql::{PostgreSqlDataSource, PostgreSqlConfig};
pub use redis::{RedisDataSource, RedisConfig};
pub use mysql::{MySqlDataSource, MySqlConfig};
pub use sqlite::{SqliteDataSource, SqliteConfig};
pub use mongodb::{MongoDBDataSource, MongoDBConfig};
pub use s3::{S3DataSource, S3Config};
pub use elasticsearch::{ElasticsearchDataSource, ElasticsearchConfig};

use std::collections::HashMap;
use async_trait::async_trait;
use serde_json::Value;

/// 数据源查询结果
#[derive(Debug, Clone)]
pub struct DataSourceResult {
    /// 查询是否成功
    pub success: bool,
    /// 返回的数据
    pub data: Value,
    /// 错误信息
    pub error: Option<String>,
    /// 查询统计信息
    pub stats: DataSourceStats,
}

/// 数据源统计信息
#[derive(Debug, Clone)]
pub struct DataSourceStats {
    /// 执行时间(毫秒)
    pub execution_time_ms: f64,
    /// 处理的行数
    pub rows_processed: u64,
    /// 处理的字节数
    pub bytes_processed: u64,
}

/// 数据源查询请求
#[derive(Debug, Clone)]
pub struct DataSourceQuery {
    /// 查询ID
    pub id: String,
    /// 查询内容
    pub content: String,
    /// 查询参数
    pub parameters: HashMap<String, Value>,
}

/// 数据源trait
#[async_trait]
pub trait DataSource: Send + Sync {
    /// 数据源名称
    fn name(&self) -> &str;
    
    /// 数据源描述
    fn description(&self) -> &str;
    
    /// 连接到数据源
    async fn connect(&mut self) -> anyhow::Result<()>;
    
    /// 断开连接
    async fn disconnect(&mut self) -> anyhow::Result<()>;
    
    /// 检查连接状态
    async fn is_connected(&self) -> bool;
    
    /// 执行查询
    async fn execute_query(&mut self, query: DataSourceQuery) -> anyhow::Result<DataSourceResult>;
    
    /// 健康检查
    async fn health_check(&self) -> anyhow::Result<Value>;
}

/// 数据源管理器
pub struct DataSourceManager {
    sources: HashMap<String, Box<dyn DataSource>>,
}

impl DataSourceManager {
    /// 创建新的数据源管理器
    pub fn new() -> Self {
        Self {
            sources: HashMap::new(),
        }
    }

    /// 初始化默认数据源
    pub async fn initialize_default_sources(&mut self) -> anyhow::Result<()> {
        // 注册内存数据源
        let mut memory_ds = MemoryDataSource::new();
        memory_ds.connect().await?;
        self.register_source("memory".to_string(), Box::new(memory_ds));

        // 注册文件系统数据源
        let mut fs_ds = FileSystemDataSource::new("./".to_string()); // 使用当前目录
        fs_ds.connect().await?;
        self.register_source("filesystem".to_string(), Box::new(fs_ds));

        // 注册HTTP API数据源
        let mut http_ds = HttpApiDataSource::new("https://api.example.com".to_string());
        http_ds.connect().await?;
        self.register_source("http".to_string(), Box::new(http_ds));

        // 注册PostgreSQL数据源（如果配置了的话）
        if let Ok(database_url) = std::env::var("DATABASE_URL") {
            let config = PostgreSqlConfig {
                database_url,
                max_connections: 10,
                connect_timeout: 30,
                query_timeout: 60,
            };
            let mut pg_ds = PostgreSqlDataSource::new(config);
            if pg_ds.connect().await.is_ok() {
                self.register_source("postgresql".to_string(), Box::new(pg_ds));
            }
        }

        // 注册Redis数据源（如果配置了的话）
        if let Ok(redis_url) = std::env::var("REDIS_URL") {
            let config = RedisConfig {
                url: redis_url,
                database: 0,
                connect_timeout: 30,
                command_timeout: 10,
            };
            let mut redis_ds = RedisDataSource::new(config);
            if redis_ds.connect().await.is_ok() {
                self.register_source("redis".to_string(), Box::new(redis_ds));
            }
        }

        // 注册MySQL数据源（如果配置了的话）
        if let Ok(mysql_url) = std::env::var("MYSQL_URL") {
            let config = MySqlConfig {
                database_url: mysql_url,
                max_connections: 10,
                connect_timeout: 30,
                query_timeout: 60,
            };
            let mut mysql_ds = MySqlDataSource::new(config);
            if mysql_ds.connect().await.is_ok() {
                self.register_source("mysql".to_string(), Box::new(mysql_ds));
            }
        }

        // 注册SQLite数据源（如果配置了的话）
        if let Ok(sqlite_path) = std::env::var("SQLITE_PATH") {
            let config = SqliteConfig {
                database_path: sqlite_path,
                max_connections: 5,
                connect_timeout: 30,
                query_timeout: 60,
                create_if_missing: true,
            };
            let mut sqlite_ds = SqliteDataSource::new(config);
            if sqlite_ds.connect().await.is_ok() {
                self.register_source("sqlite".to_string(), Box::new(sqlite_ds));
            }
        } else {
            // 默认注册内存SQLite数据源
            let config = SqliteConfig::default();
            let mut sqlite_ds = SqliteDataSource::new(config);
            if sqlite_ds.connect().await.is_ok() {
                self.register_source("sqlite_memory".to_string(), Box::new(sqlite_ds));
            }
        }

        // 注册MongoDB数据源（如果配置了的话）
        if let Ok(mongodb_url) = std::env::var("MONGODB_URL") {
            let config = MongoDBConfig {
                connection_string: mongodb_url,
                database_name: std::env::var("MONGODB_DATABASE").unwrap_or_else(|_| "test".to_string()),
                connect_timeout_seconds: 30,
                query_timeout_seconds: 60,
                max_connections: 10,
            };
            let mut mongodb_ds = MongoDBDataSource::new(config);
            if mongodb_ds.connect().await.is_ok() {
                self.register_source("mongodb".to_string(), Box::new(mongodb_ds));
            }
        }

        Ok(())
    }
    
    /// 注册数据源
    pub fn register_source(&mut self, id: String, source: Box<dyn DataSource>) {
        self.sources.insert(id, source);
    }
    
    /// 获取数据源
    pub fn get_source(&mut self, id: &str) -> Option<&mut Box<dyn DataSource>> {
        self.sources.get_mut(id)
    }
    
    /// 列出所有数据源
    pub fn list_sources(&self) -> Vec<&str> {
        self.sources.keys().map(|k| k.as_str()).collect()
    }
    
    /// 连接所有数据源
    pub async fn connect_all(&mut self) -> anyhow::Result<()> {
        for (id, source) in &mut self.sources {
            tracing::info!("连接数据源: {}", id);
            source.connect().await?;
        }
        Ok(())
    }
    
    /// 断开所有数据源
    pub async fn disconnect_all(&mut self) -> anyhow::Result<()> {
        for (id, source) in &mut self.sources {
            tracing::info!("断开数据源: {}", id);
            source.disconnect().await?;
        }
        Ok(())
    }
    
    /// 执行查询
    pub async fn execute_query(&mut self, source_id: &str, query: DataSourceQuery) -> anyhow::Result<DataSourceResult> {
        if let Some(source) = self.sources.get_mut(source_id) {
            source.execute_query(query).await
        } else {
            Err(anyhow::anyhow!("数据源不存在: {}", source_id))
        }
    }
}

impl Default for DataSourceManager {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_data_source_manager() {
        let mut manager = DataSourceManager::new();
        
        // 注册内存数据源
        let memory_source = Box::new(MemoryDataSource::new());
        manager.register_source("memory".to_string(), memory_source);
        
        // 检查数据源列表
        let sources = manager.list_sources();
        assert_eq!(sources.len(), 1);
        assert!(sources.contains(&"memory"));
        
        // 连接数据源
        manager.connect_all().await.unwrap();
        
        // 执行查询
        let query = DataSourceQuery {
            id: "test".to_string(),
            content: "SELECT * FROM users".to_string(),
            parameters: HashMap::new(),
        };
        
        let result = manager.execute_query("memory", query).await.unwrap();
        if !result.success {
            println!("查询失败: {:?}", result.error);
        }
        assert!(result.success);
        
        // 断开连接
        manager.disconnect_all().await.unwrap();
    }

    #[tokio::test]
    async fn test_postgresql_data_source_creation() {
        let config = PostgreSqlConfig::default();
        let data_source = PostgreSqlDataSource::new(config);

        assert_eq!(data_source.name(), "PostgreSQL");
        assert_eq!(data_source.description(), "PostgreSQL数据库数据源");
        assert!(!data_source.is_connected().await);
    }

    #[tokio::test]
    async fn test_initialize_default_sources() {
        let mut manager = DataSourceManager::new();

        // 初始化默认数据源
        manager.initialize_default_sources().await.unwrap();

        // 验证数据源已注册
        let sources = manager.list_sources();
        assert!(sources.contains(&"memory"));
        assert!(sources.contains(&"filesystem"));
        assert!(sources.contains(&"http"));

        // 如果设置了DATABASE_URL环境变量，PostgreSQL也应该被注册
        if std::env::var("DATABASE_URL").is_ok() {
            assert!(sources.contains(&"postgresql"));
        }

        // 如果设置了REDIS_URL环境变量，Redis也应该被注册
        if std::env::var("REDIS_URL").is_ok() {
            assert!(sources.contains(&"redis"));
        }
    }

    #[tokio::test]
    async fn test_redis_data_source_creation() {
        let config = RedisConfig::default();
        let data_source = RedisDataSource::new(config);

        assert_eq!(data_source.name(), "Redis");
        assert_eq!(data_source.description(), "Redis内存数据库数据源");
        assert!(!data_source.is_connected().await);
    }
}
